package Modelo;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.Vector;

public class Conexion {
	
	private Connection conexion;
	private InterfazBD interfazBD;

	public Conexion (){
		this.iniciarBD();
	}
	
	/**
	 * Inicia la BD usando la configuracion establecida en el fichero properties
	 */
	public void iniciarBD(){
			Properties props = new Properties();
			try{
				FileInputStream in = new FileInputStream("./Propiedades/properties");
				props.load(in);
				in.close();
			}
			catch (Exception e){
				System.out.println(e);
				System.out.println("No se ha podido leer el archivo database.properties.");
				//System.exit(-1);
			}
	
			String drivers = props.getProperty("jdbc.drivers");
			if(drivers != null){
				/*Aqui un try-catch*/
				System.setProperty("jdbc.drivers",drivers);
			}
			String url = props.getProperty("jdbc.url");
			String username = props.getProperty("jdbc.username");
			String password = props.getProperty("jdbc.password");
	
			try{
				conexion = DriverManager.getConnection(url, username, password);
			}
			catch(Exception e){
				System.out.println(e);
				System.out.println("No ha podido conectar el driver.");
				//System.exit(-1);
			}
	
			/* 
			 * Dependiendo del contenido del fichero database.properties
			*/
			try{
				if(drivers.equalsIgnoreCase("sun.jdbc.odbc.JdbcOdbcDriver"))
					interfazBD = new Access(conexion);
				else
					interfazBD = new Oracle(conexion);
			}
			catch (Exception e){
				System.out.println(e);
				System.out.println("No se ha podido conectar.");
				//System.exit(-1);
			}
		}
	
	public Connection getConexion(){
		return conexion;
	}


	/**
	 * Funcion String: devuelve el nombre del cliente
	 * @param dni
	 * @return
	 */
	public String dimeNombreCliente(String dni) {
		String campo[] = {"nombre"};
		String tabla[] = {"cliente"};
		String condicion[] = {"codcliente = '"+ dni + "'","activo = 'S'"};
		try{
			return ((Object[])interfazBD.obtener(campo,tabla,condicion).get(0))[0].toString();
		}catch (Exception e) {
			// En caso de que retornemos un array vacio, normalmente porque el dni introducido no se
			// encuentra en la BD, retornamos una cadena vacia y es el metodo 'esCliente' de la 
			// clase controlador el que se encarga de devolver como verdadero o falso el dni.
			return "";
		}
		
	}
	
	// METODOS DE LISTADO
	/**
	 * Funcion Vector: devuelve un Vector con el listado de los datos del cliente
	 * @param DNI
	 * @return
	 */
	public Vector listadoDatosCliente(String DNI){
    	String campo[] = {"codcliente","nombre","apellidos","direccion","tfno"};
    	String tabla[] = {"cliente"};
    	String condicion[] = {"where codcliente = '"+DNI+"'"};
    	
    	return interfazBD.obtener(campo, tabla, condicion);
    }
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de marcas
	 * @return
	 */
	public Vector listadoMarcas(){
		String campo[] = {"descripcion"};
		String tabla[] = {"marca"};
		
		return interfazBD.obtener(campo, tabla);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el codigo de la marca
	 * @param descripcion
	 * @return
	 */
	public Vector listadoCodMarca(String descripcion){
		String campo[] = {"codmarca"};
		String tabla[] = {"marca"};
		String condicion[] = {"descripcion = '"+descripcion+"'"};
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el codigo del modelo
	 * @param codmarca
	 * @return
	 */
	public Vector listadoCodModelo(String descripcion){
		String campo[] = {"codmodelo"};
		String tabla[] = {"modelo"};
		String condicion[] = {"descripcion = '"+descripcion+"'"};
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de modelos sengun marca
	 * @param marca
	 * @return
	 */
	public Vector listadoModeloMarcas(String marca){
		String campo[] = {"descripcion"};
		String tabla[] = {"modelo"};
		String condicion[] = {"marca = (select codmarca from marca where descripcion = '"+marca+"')"};
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con la ruta de la imagen del modelo segun marca y modelo
	 * @param marca
	 * @param modelo
	 * @return
	 */
	public Vector listadoImagenModelo(String marca, String modelo){
		String campo[] = {"imagen"};
		String tabla[] = {"modelo"};
		String condicion[] = {"marca = (select codmarca from marca where descripcion = '"+marca+"')", "descripcion = '"+modelo+"'"};
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de combustibles segun del modelo
	 * @param modelo
	 * @return
	 */
	public Vector listadoCombustibles(String modelo){
    	String campo[] = {"combustible"};
    	String tabla[] = {"motorizacion"};
    	String condicion[] = {"codmotor IN (select motor from version where modelo =" +
    			"(select codmodelo from modelo where descripcion = '"+modelo+"'))"};
    	
    	return interfazBD.obtenerDistinct(campo,tabla,condicion);
    }
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de cv segun el modelo y combustible
	 * @param modelo
	 * @param combustible
	 * @return
	 */
	public Vector listadoCV(String modelo, String combustible) {
		String campo[] = { "cv" };
		String tabla[] = { "motorizacion" };
		String condicion[] = { "codmotor IN (select motor " +
											"from version " +
											"where modelo = (select codmodelo " +
															"from modelo " +
															"where descripcion = '"+modelo+"' " +
															"AND combustible = '" + combustible + "'))" };

		return interfazBD.obtenerDistinct(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de las motorizaciones segun modelo, combus y cv
	 * @param modelo
	 * @param combustible
	 * @param cv
	 * @return
	 */
	public Vector listadoMotorizacion(String modelo, String combustible, int cv) {
		String campo[] = { "descripcion" };
		String tabla[] = { "motorizacion" };
		String condicion[] = { "codmotor IN (select motor " +
											"from version " +
											"where modelo = (select codmodelo " +
															"from modelo " +
															"where descripcion = '"+modelo+"' " +
															"AND combustible = '" + combustible + "')" +
															"AND cv = '"+cv+"')" };

		return interfazBD.obtenerDistinct(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de motores segun el modelo
	 * @param modelo
	 * @return
	 */
	public Vector listadoMotor(String modelo){
		String campo[] = {"cilindrada"};
		String tabla[] = {"motorizacion"};
		String condicion[] = {"where codmotor IN (select motor from vehiculo where modelo in (select codmodelo" +
				"from modelo where descripcion like '"+modelo+"'))"};
		
		return interfazBD.obtenerDistinct(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de operaciones
	 * @return
	 */
	public Vector listadoOperacion(){
		String campo[] = {"descripcion", "precio"};
		String tabla[] = {"operacion", "detoprep"};
		String condicion[] = {"codoperacion = operacion"};
		
		return interfazBD.obtenerDistinct(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de productos
	 * @return
	 */
	public Vector listadoProductos(){
		return interfazBD.obtenerArticulo();
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de los productos que se cargaran en
	 * el panel Panel_MCliente_Tienda
	 * @param producto
	 * @return
	 */
	public Vector listadoProductosTabla(String producto){
		String campo[] = { "imagen","descripcion","preciounitario","codarticulo" };
		String tabla[] = { "articulo" };
		String condicion[] = { "descripcion like '"+producto+"%'" };
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de coches para la vista del administrador
	 * @param campoFiltrado
	 * @return
	 */
	public Vector listadoCochesAdmin(String campoFiltrado){
		return interfazBD.obtenerCocheAdmin(campoFiltrado);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de articulos para cargar la tabla en la
	 * vista del administrador
	 * @param campoFiltrado
	 * @return
	 */
	public Vector listadoArticulosAdmin(String campoFiltrado){
		String campo[] = { "codarticulo","descripcion","preciounitario","imagen" };
		String tabla[] = { "articulo order by "+campoFiltrado };
		
		return interfazBD.obtener(campo, tabla);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de articulos filtrado por un campo para cargar 
	 * la tabla en la vista del administrador
	 * @param campoFiltrado
	 * @return
	 */
	public Vector listadoArticulosAdminFiltrado(String campoFiltrado, String cadenaFiltrado){
		String campo[] = { "codarticulo","descripcion","preciounitario","imagen" };
		String tabla[] = { "articulo" };
		String condicion[] = { campoFiltrado+" like '%"+cadenaFiltrado+"%' order by "+campoFiltrado };
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de clientes para cargar la tabla en la
	 * vista del administrador
	 * @param campoFiltrado
	 * @return
	 */
	public Vector listadoClientesAdmin(String campoFiltrado){
		String campo[] = { "codcliente","nombre", "apellidos", "direccion", "tfno"};
		String tabla[] = { "cliente" };
		String condicion[] = { "activo = 'S' order by "+campoFiltrado };
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 * Funcion Vector: devuelve un Vector con el listado de clientes filtrado por un campo para cargar 
	 * la tabla en la vista del administrador
	 * @param campoFiltrado
	 * @param cadenaFiltrado
	 * @return
	 */
	public Vector listadoClientesAdminFiltrado(String campoFiltrado, String cadenaFiltrado){
		String campo[] = { "codcliente","nombre", "apellidos", "direccion", "tfno"};
		String tabla[] = { "cliente" };
		String condicion[] = { campoFiltrado+" like '%"+cadenaFiltrado+"%'","activo = 'S' order by "+campoFiltrado };
		
		return interfazBD.obtener(campo, tabla, condicion);
	}
	
	/**
	 *  Funcion Vector: devuelve un Vector con el valor maximo de un campo y una tabla pasados como argumento
	 * @param campoCod
	 * @param tablaBusqueda
	 * @return
	 */
	public Vector obtenerCodMaximo(String campoCod, String tablaBusqueda){
		String campo[] = { "MAX("+campoCod+")" };
		String tabla[] = { tablaBusqueda };
		
		return interfazBD.obtener(campo, tabla);
	}
	
	// METODOS DE INSERCION
	/**
	 * Inserta un articulo en la tabla ARTICULO
	 * @param descripcion
	 * @param precioUnitario
	 * @param imagen
	 */
	public void insertarArtriculo(String descripcion, Long precioUnitario, String imagen){
		interfazBD.insertarArticulo(descripcion, precioUnitario, imagen);
	}
	
	/**
	 * Inserta un articulo en la tabla ARTICULO
	 * @param codArticulo
	 * @param descripcion
	 * @param precioUnitario
	 * @param imagen
	 */
	public void insertarArtriculo(Long codArticulo, String descripcion, Long precioUnitario, String imagen){
		interfazBD.insertarArtriculo(codArticulo, descripcion, precioUnitario, imagen);
	}
	
	/**
	 * Inserta un cliente en la tabla CLIENTE
	 * @param codCliente
	 * @param nombre
	 * @param apellidos
	 * @param direccion
	 * @param tfno
	 */
	public void insertarCliente(String codCliente, String nombre, String apellidos, String direccion, String tfno){
		interfazBD.insertarCliente(codCliente, nombre, apellidos, direccion, tfno);
	}
	
	/**
	 * Inserta una marca en la tabla MARCA
	 * @param codMarca
	 * @param descripcion
	 * @param precioHoraTaller
	 */
	public void insertarMarca(Long codMarca, String descripcion, Long precioHoraTaller){
		interfazBD.insertarMarca(codMarca, descripcion, precioHoraTaller);
	}
	
	/**
	 * Inserta un modelo en la tabla MODELO
	 * @param codModelo
	 * @param descripcion
	 * @param marca
	 */
	public void insertarModelo(Long codModelo, String descripcion, Long marca){
		interfazBD.insertarModelo(codModelo, descripcion, marca);
	}
	
	/**
	 * Inserta una motorizacion en la tabla MOTORIZACION
	 * @param codMotor
	 * @param descripcion
	 * @param cilindrada
	 * @param cv
	 * @param combustible
	 * @param cajacambios
	 */
	public void insertarMotorizacion(Long codMotor, String descripcion, String cilindrada, Long cv, String combustible, String cajacambios){
		interfazBD.insertarMotorizacion(codMotor, descripcion, cilindrada, cv, combustible, cajacambios);
	}
	
	/**
	 * Inserta una version en la tabla VERSION
	 * @param codModelo
	 * @param motor
	 * @param activo
	 */
	public void insertarVersion(Long codModelo, Long motor, String activo){
		interfazBD.insertarVersion(codModelo, motor, activo);
	}
	
	/**
	 * Inserta una venta en la tabla VENTASTIENDA
	 * @param codVenta
	 * @param cliente
	 * @param articulo
	 * @param cantidad
	 */
	public void insertarVentaTienda(Long codVenta, String cliente, Long articulo, Long cantidad){
		interfazBD.insertarVentaTienda(codVenta, cliente, articulo, cantidad);
	}
	
	// METODOS DE ACTUALIZACION
	/**
	 * Actualiza un articulo de la tabla ARTICULO
	 * @param descripcion
	 * @param precioUnitario
	 * @param imagen
	 * @param codigo
	 */
	public void actualizarArtriculo(String descripcion, Long precioUnitario, String imagen, String codigo){
		interfazBD.actualizarArticulo(descripcion, precioUnitario, imagen, codigo);
	}
	
	/**
	 * Actualiza un cliente de la tabla CLIENTE
	 * @param nombre
	 * @param apellidos
	 * @param direccion
	 * @param tfno
	 * @param codigo
	 */
	public void actualizarCliente(String nombre, String apellidos, String direccion, String tfno, String codigo){
		interfazBD.actualizarCliente(nombre, apellidos, direccion, tfno, codigo);
	}
	
	/**
	 * Actualiza una marca de la tabla MARCA
	 * @param descripcion
	 * @param codigo
	 */
	public void actualizarMarca(String descripcion, String codigo){
		interfazBD.actualizarMarca(descripcion, codigo);
	}
	
	/**
	 * Actualiza un modelo de la tabla MODELO
	 * @param descripcion
	 * @param codigo
	 */
	public void actualizarModelo(String descripcion, String codigo){
		interfazBD.actualizarModelo(descripcion, codigo);
	}
	
	/**
	 * Actualiza una motorizacion de la tabla MOTORIZACION
	 * @param descripcion
	 * @param cilindrada
	 * @param cv
	 * @param combustible
	 * @param cajacambios
	 * @param codigo
	 */
	public void actualizarMotorizacion(String descripcion, String cilindrada, Long cv, String combustible, String cajacambios, String codigo){
		interfazBD.actualizarMotorizacion(descripcion, cilindrada, cv, combustible, cajacambios, codigo);
	}
	
	// METODOS DE ELIMINACION
	/**
	 * Elimina un objeto de la tabla especificada
	 * @param tabla
	 * @param campoCod
	 * @param codigo
	 */
	public void eliminarDefinitivo(String tabla, String campoCod, int codigo){
		interfazBD.eliminarDefinitivo(tabla, campoCod, codigo);
	}
	
	/**
	 * Eliminacion parcial: no elimina la fila de la tabla realmente, solamente acualiza el campo ACTIVO a 'N'
	 * @param tabla
	 * @param campoCod
	 * @param codigo
	 */
	public void eliminarParcial(String tabla, String campoCod, String codigo){
		interfazBD.eliminarParcial(tabla, campoCod, codigo);
	}
	
}
